using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;

using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Diagnostics;
using System.Text;
using Microsoft.Office.Server.UserProfiles;
using System.Web.UI.WebControls;

using Microsoft.SharePoint.Administration;

namespace eGov.SharePoint.MyPeeps.WebParts
{
    [Guid("68c06400-3791-420b-a2cc-e8103c0e0f41")]
    public class FollowMe : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private bool _error = false;
        private string _myProperty = null;
        private string rawAccountNameIncludingDomain = string.Empty;
        private string[] splittedAccountName = null;
        private string rawUserNameStringFromURL = string.Empty;
        private SPUser currentSPUser = null;
        private string currentUserLoginNameIncludingDomain = string.Empty;
        private string currentUserName = string.Empty;
        private string siteUrlOfTargetUser = string.Empty;

        const string FOLLOWER_REQUEST_LIST = "Follower requests";

        enum followState { NONE, FOLLOWME, FOLLOWING, WAITINGAPPROVAL };

        ImageButton btnFollowMe = null;
        followState _followState = followState.NONE;


        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Property Group")]
        [WebDisplayName("MyProperty")]
        [WebDescription("Meaningless Property")]
        public string MyProperty
        {
            get
            {
                if (_myProperty == null)
                {
                    _myProperty = "Hello SharePoint";
                }
                return _myProperty;
            }
            set { _myProperty = value; }
        }


        public FollowMe()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        private bool InitializeVariables()
        {

            //Foreign User - User who's profile page being visited
            if (this.Context.Request.QueryString["accountname"] != null)
                rawAccountNameIncludingDomain = this.Context.Request.QueryString["accountname"].ToLower();

            if (string.IsNullOrEmpty(rawAccountNameIncludingDomain))
                return false;
            else
                splittedAccountName = rawAccountNameIncludingDomain.Split('\\');

            //Split the acount CONTOSO\user
            if (splittedAccountName != null && splittedAccountName.Length > 1)
                rawUserNameStringFromURL = splittedAccountName[1];
            else
                return false;


            //Current User
            currentSPUser = SPContext.Current.Site.OpenWeb().CurrentUser;
            if (currentSPUser != null)
                currentUserLoginNameIncludingDomain = currentSPUser.LoginName.ToLower();
            else
                return false;

            splittedAccountName = null;
            if (!string.IsNullOrEmpty(currentUserLoginNameIncludingDomain))
                splittedAccountName = currentUserLoginNameIncludingDomain.Split('\\');

            //Split the acount CONTOSO\user
            if (splittedAccountName != null && splittedAccountName.Length > 1)
                currentUserName = splittedAccountName[1];


            //if a useraccount is not in browser then do nothing
            if (string.IsNullOrEmpty(rawUserNameStringFromURL) || rawUserNameStringFromURL.Length == 0)
                return false;

            //Make sure accountname is not the same surrent user
            if (rawAccountNameIncludingDomain.ToLower() == currentSPUser.LoginName.ToLower())
                return false;


            // SPWebApplication webApp = SPContext.Current.Site.WebApplication;
            // SPSiteCollection siteColls = webApp.Sites;
            //string webAppUrl = siteColls[0].Url;

            UserProfileManager profileManager = new UserProfileManager(SPServiceContext.GetContext(SPContext.Current.Site));
            string s = profileManager.PersonalSiteInclusion.Trim(new char[] { '/' });
            string siteUrl = "/" + s + "/" + rawUserNameStringFromURL.Replace(".", "_");

            siteUrlOfTargetUser = SPContext.Current.Site.WebApplication.Sites["/"].Url + siteUrl;
            return true;
        }

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {

                    base.CreateChildControls();
                    //RMV: Initialized follow me control

                    InitFollowButtonControls();
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        //
        private void InitFollowButtonControls()
        {
            //Create button
            InitFollowButtonState();
            UpdateFollowUpState();
        }

        //RMV 8/20/2009
        // InitFollowButtonState(): Initialized the state of the follow button to be presented in the page
        //POST CONDITION
        // _followState = followState.FOLLOWING: If user is already in account and approved.
        // _followState = followState.WAITINGAPPROVAL: If user is already in account and waiting for approval
        // _followState = followState.FOLLOWME: User is not yet a follower
        private void InitFollowButtonState()
        {
            SPSite currentSite = SPContext.Current.Site;
            SPWeb currentWeb = SPContext.Current.Web;

            _followState = followState.NONE;

            try
            {
                //The account can only be obtained from the browser
                if (!InitializeVariables())
                    return;

                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    try
                    {
                        char[] delim = { '/' };
                        UserProfileManager profileManager = new UserProfileManager(SPServiceContext.GetContext(SPContext.Current.Site));
                        using (SPSite userSite = SPContext.Current.Site.WebApplication.Sites[profileManager.PersonalSiteInclusion.TrimEnd('/') + "/" + rawUserNameStringFromURL.Replace(".", "_")])
                        {
                            if (userSite == null)
                            {
                                this.Controls.Clear();
                                this.Controls.Add(new LiteralControl("User Did not create an account. Request to follow the user is invalid at this time."));
                                return;
                            }
                        }

                    }
                    catch (Exception)
                    {
                        this.Controls.Clear();
                        this.Controls.Add(new LiteralControl("User Did not create an account. Request to follow the user is invalid at this time."));

                    }

                    using (SPSite ElevatedsiteColl = new SPSite(siteUrlOfTargetUser))
                    {
                        using (SPWeb ElevatedSite = ElevatedsiteColl.OpenWeb())
                        {
                            if (ElevatedSite == null || ElevatedSite.Lists == null)
                                return;

                            if (listExists(ElevatedSite.Lists, FOLLOWER_REQUEST_LIST) == false)
                            {
                                //Note: This should not happen once the feauture is activated in all site
                                _followState = followState.NONE;
                                UpdateFollowUpState();
                                return;

                            }

                            List<Colleague> colls = new List<Colleague>();
                            colls = CSP.Model.DataAccess.SPDataAccess.getColleagues(currentUserLoginNameIncludingDomain);

                            foreach (Colleague c in colls)
                            {
                                if (c.Profile["AccountName"].Value.ToString().ToLower() == rawAccountNameIncludingDomain.ToLower())
                                {
                                    _followState = followState.FOLLOWING;
                                    return;
                                }
                            }

                            SPList idList = ElevatedSite.Lists[FOLLOWER_REQUEST_LIST];
                            if (idList != null)
                            {
                                foreach (SPListItem item in idList.Items)
                                {
                                    SPFieldUser follower = (SPFieldUser)item.Fields["Follower"];
                                    SPFieldUserValue user = (SPFieldUserValue)follower.GetFieldValue(item["Follower"].ToString());
                                    SPUser currentFollower = user.User;

                                    //Make sure the user does not already exist in the list                                   
                                    //string currentFollower = item["Follower"].ToString().ToLower();
                                    string strCurrentFollowerLoginName = currentFollower.LoginName;
                                    if (strCurrentFollowerLoginName.ToLower().Contains(currentUserLoginNameIncludingDomain.ToLower()))
                                    {
                                        Boolean approved = Convert.ToBoolean(item["IsAllowed"]);
                                        if (!approved)
                                        // _followState = followState.FOLLOWING;
                                        // else
                                        {
                                            _followState = followState.WAITINGAPPROVAL;
                                            return;
                                        }

                                    }

                                    strCurrentFollowerLoginName = item["Follower"].ToString().ToLower();
                                    //User was found
                                    if (strCurrentFollowerLoginName.Contains(currentUserLoginNameIncludingDomain.ToLower()))
                                    {
                                        Boolean approved = Convert.ToBoolean(item["IsAllowed"]);
                                        if (!approved)
                                        //    _followState = followState.FOLLOWING;
                                        //else
                                        {
                                            _followState = followState.WAITINGAPPROVAL;
                                            return;
                                        }

                                    }
                                }
                            }
                        }
                    }




                    //User to be added is not yet a follower
                    _followState = followState.FOLLOWME;
                });


                //    SPSecurity.RunWithElevatedPrivileges(delegate()
                //    {
                //        using (SPSite ElevatedsiteColl = new SPSite(siteUrlOfTargetUser))
                //        {
                //            using (SPWeb ElevatedSite = ElevatedsiteColl.OpenWeb())
                //            {
                //                if (ElevatedSite == null || ElevatedSite.Lists == null)
                //                    return;

                //                if (listExists(ElevatedSite.Lists, FOLLOWER_REQUEST_LIST) == false)
                //                {
                //                    //Note: This should not happen once the feauture is activated in all site
                //                    _followState = followState.NONE;
                //                    UpdateFollowUpState();
                //                    return;
                //                }


                //                //List<Colleague> colls = new List<Colleague>();
                //                //colls = CSP.Model.DataAccess.SPDataAccess.getColleagues(currentUserLoginNameIncludingDomain );

                //                //foreach (Colleague c in colls)
                //                //{
                //                //    if (c.Profile["AccountName"].Value.ToString() == accountname)
                //                //    {
                //                //        _followState = followState.FOLLOWING;
                //                //        return;
                //                //    }
                //                //}

                //                SPList idList = ElevatedSite.Lists[FOLLOWER_REQUEST_LIST];
                //                if (idList != null)
                //                {
                //                    foreach (SPListItem item in idList.Items)
                //                    {
                //                        SPFieldUser follower = (SPFieldUser)item.Fields["Follower"];
                //                        SPFieldUserValue user = (SPFieldUserValue)follower.GetFieldValue(item["Follower"].ToString());
                //                        SPUser currentFollower = user.User;

                //                        //Make sure the user does not already exist in the list                                   
                //                        //string currentFollower = item["Follower"].ToString().ToLower();
                //                        string strCurrentFollowerLoginName = currentFollower.LoginName;
                //                        if (strCurrentFollowerLoginName.ToLower().Contains(rawAccountNameIncludingDomain.ToLower()))
                //                        {
                //                            Boolean approved = Convert.ToBoolean(item["IsAllowed"]);
                //                            if (approved == true)
                //                            {    //_followState = followState.FOLLOWING;
                //                                //else
                //                                _followState = followState.FOLLOWING;
                //                                UpdateFollowUpState();
                //                                return;
                //                            }
                //                        }

                //                        strCurrentFollowerLoginName = currentFollower.LoginName;// item["Follower"].ToString().ToLower();
                //                        //User was found
                //                        if (strCurrentFollowerLoginName.Contains(rawAccountNameIncludingDomain.ToLower()))
                //                        {
                //                            Boolean approved = Convert.ToBoolean(item["IsAllowed"]);
                //                            if (approved == true)
                //                            {  //_followState = followState.FOLLOWING;
                //                                //else
                //                                _followState = followState.FOLLOWING;
                //                                UpdateFollowUpState();
                //                                return;
                //                            }
                //                        }
                //                    }
                //                }
                //            }
                //        }
                //        //User to be added is not yet a follower
                //        _followState = followState.FOLLOWME;
                //    });

            }
            catch (Exception exp)
            {

                Debug.WriteLine(exp.ToString());
                HandleException(exp);

            }
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();
                    //RMV: Uncomment script control . DO NOT DELETE IT for future reference
                    //       this.Page.ClientScript.RegisterClientScriptInclude("FollowMe", "~/_layouts/CSP%20Follow%20Me/FollowMe.js");
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }

        //RV Dont't DELETE.  For refrence
        protected override void RenderContents(HtmlTextWriter writer)
        {
            base.RenderContents(writer);


            ////    writer.Write("<input type=\"button\" id=\"btnHidden\" style=\"display:none\" runat=\"server\" onserverclick=\"click_test\">");
            ////    writer.Write("<span id=\"link0\" onmouseover=\"displayFollowRequest (0);\" onmouseout=\"hideFollowRequest();\"><img src=\"followme.gif\" alt=\"Follow Me!\" /></span>");
            ////    writer.Write("<div id=\"tooltipBox\" onmouseover=\"clearRequestInterval();highlightRequest('itxtTbl');\" onmouseout=\"hideFollowRequest();unhighlightRequest('itxtTbl');\" style=\"z-index:5000;position:absolute;cursor:pointer;\"></div>");
        }

        //Renders the HTML for the body of a Web Part to the client
        //protected override void RenderWebPart(HtmlTextWriter output)
        //{
        //    RenderChildren(output);
        //}


        //protected void btnSubmitFollowMe_ClientClick(object sender, EventArgs e)
        public void btnFollowMe_Click(object sender, ImageClickEventArgs e)
        {
            writeToFollowerList();
        }

        protected void writeToFollowerList()
        {
            if (!InitializeVariables())
                return;

            SPSite currentSite = SPContext.Current.Site;
            SPWeb currentWeb = SPContext.Current.Web;

            try
            {

                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite ElevatedsiteColl = new SPSite(siteUrlOfTargetUser))
                    {
                        using (SPWeb ElevatedSite = ElevatedsiteColl.OpenWeb())
                        {
                            if (ElevatedSite == null || ElevatedSite.Lists == null)
                                return;

                            //IMPORTANT: Allow update to the database.
                            ElevatedSite.AllowUnsafeUpdates = true;

                            if (listExists(ElevatedSite.Lists, FOLLOWER_REQUEST_LIST) == false)
                            {
                                //Note: This should not happen once the feauture is activated in all site
                                _followState = followState.NONE;
                                UpdateFollowUpState();
                                return;

                            }

                            SPList idList = ElevatedSite.Lists[FOLLOWER_REQUEST_LIST];

                            if (idList != null)
                            {
                                foreach (SPListItem item in idList.Items)
                                {
                                    //Make sure the user does not already exist in the list
                                    // string currentFollower = item["Follower"].ToString().Replace("5;#", "");
                                    string currentFollower = item["Follower"].ToString().ToLower();


                                    SPFieldUser follower = (SPFieldUser)idList.Fields["Follower"];
                                    SPFieldUserValue user = (SPFieldUserValue)follower.GetFieldValue(item["Follower"].ToString());
                                    SPUser userObject = user.User;
                                    //string l = userObject.LoginName;

                                    //User was found
                                    if (currentFollower.Contains(currentUserLoginNameIncludingDomain.ToLower()))
                                    {
                                          _followState = followState.WAITINGAPPROVAL;
                                        return;
                                    }

                                }

                                SPListItem listItemAdd = idList.Items.Add();
                                //SPUser spuser = ElevatedSite.AllUsers[currentUserLoginNameIncludingDomain ];
                                SPUser destinationUser = ElevatedSite.EnsureUser(currentSPUser.LoginName);
                                listItemAdd["Title"] = currentSPUser.Name;
                                listItemAdd["Follower"] = new SPFieldUserValue(ElevatedSite, destinationUser.ID, destinationUser.LoginName);

                                listItemAdd.Update();

                                //Change the followstate
                                _followState = followState.WAITINGAPPROVAL;
                                UpdateFollowUpState();
                            }
                        }
                    }
                });

            }
            catch (Exception exp)
            {

                Debug.WriteLine(exp.ToString());
                HandleException(exp);

            }

        }

        private void UpdateFollowUpState()
        {
            if (btnFollowMe != null)
            {
                btnFollowMe.Visible = false;
            }

            switch (_followState)
            {
                case followState.FOLLOWING:
                    btnFollowMe = new ImageButton();
                    btnFollowMe.ImageUrl = "~/_layouts/eGov/Follow Me/following.gif";
                    btnFollowMe.Enabled = false;
                    break;
                case followState.FOLLOWME:
                    btnFollowMe = new ImageButton();
                    btnFollowMe.ImageUrl = "~/_layouts/eGov/Follow Me/followme.gif";
                    btnFollowMe.Enabled = true;
                    btnFollowMe.Click += new ImageClickEventHandler(btnFollowMe_Click);
                    break;
                case followState.WAITINGAPPROVAL:
                    btnFollowMe = new ImageButton();
                    btnFollowMe.ImageUrl = "~/_layouts/eGov/Follow Me/approval.gif";
                    btnFollowMe.Enabled = false;
                    break;
                default:
                    break;
            }
            if (btnFollowMe != null)
            {
                btnFollowMe.Visible = true;
                Controls.Add(btnFollowMe);

            }

        }

        bool listExists(SPListCollection collection, string title)
        {
            foreach (SPList list in collection)
            {
                if (list.Title == title)
                {
                    return true;
                }
            }
            return false;
        }




    }
}
